package pokemon;

import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;

import javax.imageio.ImageIO;

public class Pokemon implements Comparable<Pokemon>
{
	protected String name;
	protected Types type1, type2;
	protected String ability1, ability2, ability3;
	protected int hp,
		attack,
		defense,
		specAtk,
		specDef,
		speed;
	protected int id;
	protected int form;
	protected ArrayList<Types> weaknessesX2 = new ArrayList<Types>();
	protected ArrayList<Types> resistancesX2 = new ArrayList<Types>();
	protected ArrayList<Types> weaknessesX4 = new ArrayList<Types>();
	protected ArrayList<Types> resistancesX4 = new ArrayList<Types>();
	protected ArrayList<Types> immunities = new ArrayList<Types>();
	protected ArrayList<Types> neutral = new ArrayList<Types>();
	protected BufferedImage myImage;
	/**
	 * Use this constructor only when searching for a Pokemon by name.
	 */
	public Pokemon(String name)
	{
		this.name = name;
	}
	
	public Pokemon(int id, int form, String name, Types type1, Types type2, String ability1,
			String ability2, String ability3, int hp, int attack, int defense,
			int specAtk, int specDef, int speed)
	{
		this.id = id;
		this.form = form;
		this.name = name;
		this.type1 = type1;
		this.type2 = type2;
		this.ability1 = ability1;
		this.ability2 = ability2;
		this.ability3 = ability3;
		this.hp = hp;
		this.attack = attack;
		this.defense = defense;
		this.specAtk = specAtk;
		this.specDef = specDef;
		this.speed = speed;
		calculateTypeEffectiveness();
		setImage();
	}
	public Pokemon(int id, int form, String name, Types type1, Types type2, String ability, 
			int hp, int attack, int defense, int specAtk, int specDef, int speed)
	{
		this.id = id;
		this.form = form;
		this.name = name;
		this.type1 = type1;
		this.type2 = type2;
		this.ability1 = ability;
		this.hp = hp;
		this.attack = attack;
		this.defense = defense;
		this.specAtk = specAtk;
		this.specDef = specDef;
		this.speed = speed;
		calculateTypeEffectiveness();
		setImage();
	}
	protected void setImage()
	{
		try
	    {               
			this.myImage= ImageIO.read(new File("Sprites/"+this.getId()+"/front.png"));
	    }
		catch(Exception e)
		{
			System.out.println(e);
		}
	}
	protected void calculateTypeEffectiveness()
	{		
		for(Types attackingType : Types.values())
		{
			double type1Modifier = Pokedex.typeChart.getDamageModifier(attackingType, type1), 
				type2Modifier = Pokedex.typeChart.getDamageModifier(attackingType, type2);
			
			if(type1Modifier * type2Modifier == 2)
			{
				weaknessesX2.add(attackingType);
			}
			else if(type1Modifier * type2Modifier == 0.5)
			{
				resistancesX2.add(attackingType);
			}
			else if(type1Modifier * type2Modifier == 4)
			{
				weaknessesX4.add(attackingType);
			}
			else if(type1Modifier * type2Modifier == 0.25)
			{
				resistancesX4.add(attackingType);
			}
			else if(type1Modifier * type2Modifier == 0)
			{
				immunities.add(attackingType);
			}
			else
			{
				neutral.add(attackingType);
			}
		}	
	}	
	
	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + form;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
		{
			return true;
		}
		if (obj == null)
		{
			return false;
		}
		if (getClass() != obj.getClass())
		{
			return false;
		}
		
		Pokemon other = (Pokemon) obj;
		
		if (form != other.form)
		{
			return false;
		}
		if (name == null)
		{
			if (other.name != null)
			{
				return false;
			}
		} 
		else if (!name.equals(other.name))
		{
			return false;
		}
		return true;
	}
	

	@Override
	public int compareTo(Pokemon poke)
	{
		return this.name.compareToIgnoreCase(poke.name);
	}

	public String toString()
	{
		if(ability2 == null && ability3 == null)
		{
			return (this.getName() + " " + this.getType1().name() + " " + this.getType2().name()
					  + " " + this.getAbility1()
					  + " " + this.getHp() + " " + this.getAttack() + " " + this.getDefense()
					  + " " + this.getSpecAtk() + " " + this.getSpecDef() + " " + this.getSpeed());
		}
		if(ability2 == null)
		{
			return (this.getName() + " " + this.getType1().name() + " " + this.getType2().name()
					  + " " + this.getAbility1() + " " + this.getAbility3()
					  + " " + this.getHp() + " " + this.getAttack() + " " + this.getDefense()
					  + " " + this.getSpecAtk() + " " + this.getSpecDef() + " " + this.getSpeed());
		}
		if(ability3 == null)
		{
			return (this.getName() + " " + this.getType1().name() + " " + this.getType2().name()
					  + " " + this.getAbility1() + " " + this.getAbility2()
					  + " " + this.getHp() + " " + this.getAttack() + " " + this.getDefense()
					  + " " + this.getSpecAtk() + " " + this.getSpecDef() + " " + this.getSpeed());
		}
		return (this.getName() + " " + this.getType1().name() + " " + this.getType2().name()
				  + " " + this.getAbility1() + " " + this.getAbility2() + " " + this.getAbility3()
				  + " " + this.getHp() + " " + this.getAttack() + " " + this.getDefense()
				  + " " + this.getSpecAtk() + " " + this.getSpecDef() + " " + this.getSpeed());	
	}
	
	public String getName() {
		return name;
	}
	public Types getType1() {
		return type1;
	}
	public Types getType2() {
		return type2;
	}
	public String getAbility1() {
		return ability1;
	}
	public String getAbility2() {
		return ability2;
	}
	public String getAbility3() {
		return ability3;
	}
	public int getHp() {
		return hp;
	}
	public int getAttack() {
		return attack;
	}
	public int getDefense() {
		return defense;
	}
	public int getSpecAtk() {
		return specAtk;
	}
	public int getSpecDef() {
		return specDef;
	}
	public int getSpeed() {
		return speed;
	}
	public ArrayList<Types> getWeaknessesX2() {
		return weaknessesX2;
	}
	public ArrayList<Types> getResistancesX2() {
		return resistancesX2;
	}
	public ArrayList<Types> getWeaknessesX4() {
		return weaknessesX4;
	}
	public ArrayList<Types> getResistancesX4() {
		return resistancesX4;
	}
	public ArrayList<Types> getImmunities() {
		return immunities;
	}
	public void setWeaknessesX2(ArrayList<Types> weaknessesX2) {
		this.weaknessesX2 = weaknessesX2;
	}
	public void setResistancesX2(ArrayList<Types> resistancesX2) {
		this.resistancesX2 = resistancesX2;
	}
	public void setWeaknessesX4(ArrayList<Types> weaknessesX4) {
		this.weaknessesX4 = weaknessesX4;
	}
	public void setResistancesX4(ArrayList<Types> resistancesX4) {
		this.resistancesX4 = resistancesX4;
	}
	public void setImmunities(ArrayList<Types> immunities) {
		this.immunities = immunities;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setType1(Types type1) {
		this.type1 = type1;
	}
	public void setType2(Types type2) {
		this.type2 = type2;
	}
	public void setAbility1(String ability1) {
		this.ability1 = ability1;
	}
	public void setAbility2(String ability2) {
		this.ability2 = ability2;
	}
	public void setAbility3(String ability3) {
		this.ability3 = ability3;
	}
	public void setHp(int hp) {
		this.hp = hp;
	}
	public void setAttack(int attack) {
		this.attack = attack;
	}
	public void setDefense(int defense) {
		this.defense = defense;
	}
	public void setSpecAtk(int specAtk) {
		this.specAtk = specAtk;
	}
	public void setSpecDef(int specDef) {
		this.specDef = specDef;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getId() {
		return id;
	}
	public void setForm(int form) {
		this.form = form;
	}
	public int getForm() {
		return form;
	}
}
